package compilers.stmt;

import java.io.BufferedWriter;
import java.io.IOException;

import compilers.condition.Term;
import compilers.node.Stmt;
import compilers.table.MemScope;
import compilers.types.*;

public class Condition extends Stmt {
	//If fIf;
	Condition fExpr;
	Condition fStatement1;
	Condition fStatement2;
	Type fRes;
	
	public Condition () {}
	
	public Condition (Condition fExpr, Condition fStatement1, Condition fStatement2) {
		this.fExpr = fExpr;
		this.fStatement1 = fStatement1;
		this.fStatement2 = fStatement2;
	}
	
	public Type compute() {
		return null;
	}
	
	public void setRes(Type fRes) {
		this.setfRes(fRes);
	}

	public Type getfRes() {
		return fRes;
	}

	public void setfRes(Type fRes) {
		this.fRes = fRes;
		//System.out.println(fRes);
	}
	
	public void generate(BufferedWriter writer, MemScope scope) throws IOException {
		fStatement1.setfRes(fRes);
		fStatement2.setfRes(fRes);
		
		// optimalisation
		if (fExpr instanceof Term) {
			Term t = (Term)fExpr;
			Type tmp = t.compute();
			if (tmp != null) {
				MemScope myScope = new MemScope(scope);
				if (tmp.getfValue() > 0) {
					// expr is always true
					fStatement1.generate(writer, myScope);
				} else {
					fStatement2.generate(writer, myScope);
				}
			} else {
				generateWithoutOptimalisation(writer, scope);
			}
		}
	}
	
	public void generateWithoutOptimalisation(BufferedWriter writer, MemScope scope) throws IOException {
		MemScope myScope = new MemScope(scope);

		fExpr.setfRes(new IntType(true));
		
		String lbl1 = myScope.getUniqueLabel();
		String lbl2 = myScope.getUniqueLabel();
		
		fExpr.generate(writer, myScope);
		writer.write("fjp cond_" + lbl1 + "\n");
		
		fStatement1.generate(writer, myScope);
		writer.write("ujp cond_" + lbl2 + "\n");
		writer.write("cond_" + lbl1 + ":\n");
		fStatement2.generate(writer, myScope);
		writer.write("cond_" + lbl2 + ":\n");
	}
	
	public void print(int tab) {
		for (int i=1;i<=tab;i++){System.out.print("\t");}System.out.print("|-");
			System.out.println("Condition");
			fExpr.print(tab+1);
			fStatement1.print(tab+1);
			fStatement2.print(tab+1);
	}
}
